/*******************************************************************************
 * @file    lowpower.c
 * @author  roger.luo
 * @date    2019-04-19
 * @brief   低功耗管理
 *
 *
 * @attention
 *
 ******************************************************************************/
#ifndef _LOWPOWER_H_
#define _LOWPOWER_H_

//#include <comdef.h>
#include <stdbool.h>
#include <time.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SLEEP_TIME              3000                //单次最大休眠时间

#define MS_TICK_ACCURACY            10                  /* unit:ms */      //任务单次最小休眠间隔

// #define MIN_WAKEUP_WORK_TIME     (2*60*1000)         //唤醒后最短持续工作时长

#define MIN_SLEEP_VOTE_TIME         (3*1000)            //最小休眠投票时间，最终休眠投票小于它则不再休眠
#define MIN_ALLOW_SLEEP_TIME        (10*1000)

#define TASK_ALWAYS_SLEEP           (0xFFFFFFFF)        //任务可以一直休眠

/* MCU唤醒类型 */
#define    WAKEUP_BY_NONE       (0)
#define    WAKEUP_NEED_GPS      (1ul << 1)              /* 唤醒需要GPS开启     */
#define    WAKEUP_BY_COMCU      (1ul << 2)              /* CoMCU唤醒     */
#define    WAKEUP_BY_MODEM      (1ul << 3)              /* LTE唤醒     */
#define    WAKEUP_BY_GSENSOR    (1ul << 4)              /* GSENSOR唤醒  */
#define    WAKEUP_BY_RTC        (1ul << 7)              /* RTC定时唤醒 */

typedef enum {
    WUP_SRC_NONE  = WAKEUP_BY_NONE,
    WUP_SRC_MODEM = WAKEUP_BY_MODEM,
    WUP_SRC_COMCU = WAKEUP_BY_COMCU,
    WUP_SRC_GSNSR = WAKEUP_BY_GSENSOR,
    WUP_SRC_RTC   = WAKEUP_BY_RTC,
} wakeup_source_e;

typedef struct {
	unsigned int    type;
	const char      *name;
} wakeup_name_t;

typedef struct {
    unsigned int   rtc_wakeup_period;                   //rtc唤醒周期
    unsigned int   next_sleep_interval;                 //下1次休眠间隔
    unsigned int   sleep_wakeup_cnt;                    //睡眠唤醒次数
    volatile bool  rtcwakup;                            //rtc唤醒标志
    unsigned int   sleeptime;                           //休眠时长
    bool           deep_sleep;                          //深度休眠模式
    struct tm      lasttime;                            //休眠前的时间
    volatile wakeup_source_e wakeup_type;
} pm_t;

typedef struct {
    const char      *name;                              /* 订阅者名称 */
    unsigned int    (*canstop)(void);                   /* 休眠时长判断, 注意: 不能在接口中使用阻塞函数 */
    void            (*prestop)(void);                   /* 休眠前处理函数 */
    void            (*poststop)(void);                  /* 唤醒后处理函数 */
} sleep_item_t;

wakeup_source_e lp_wakeup_type_get(void);
void lp_wakeup_type_set(wakeup_source_e wakeup_type);
bool lp_wakeup_type_check(wakeup_source_e wakeup_type);
void lp_wakeup_type_clear(wakeup_source_e wakeup_type);
void lp_wakeup_type_set(wakeup_source_e wakeup_type);
bool lp_wakeup_type_check(wakeup_source_e wakeup_type);
void lp_wakeup_type_clear(wakeup_source_e wakeup_type);
void task_lowpower_process(void);
unsigned int lowpower_sleep_sec_get(void);

#endif
